package com.fingard.dsp.bank.directbank.icbc02;

import javax.lang.model.element.Element;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.IElecBillQuery;
import com.fingard.dsp.bank.reqrespobj.elecbillquery.*;
import com.fingard.dsp.bank.reqrespobj.elecbillquery.detail.*;
import com.fingard.text.StringHelper;
import com.fingard.util.BijectionHashMap;
import com.fingard.util.DateHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.text.ParseException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

/**
 * Created by austyn on 2017/11/9.
 */
public class ICBC02ElecBill extends ICBC02Base implements IElecBillQuery {

   /* @Override
    public RetAtsB001OperBillQry D_OperBill_Query_Req(ReqB001OperBillQry query) throws Exception {
        RetAtsB001OperBillQry retAts = new RetAtsB001OperBillQry(query.reqHeader);

        query.readRecord();
        try {
            bnkPackageID = query.reqHeader.transSeqID;
            if (bnkTransCode == null) {
                if (!StringHelper.isNullOrEmpty(query.detail.busiType) && !StringHelper.isNullOrEmpty(query.detail.queryType)
                        // 1002 提示承兑申请 3002 提示承兑撤回
                        && ((query.detail.busiType.equals("2") && (query.detail.queryType.equals("1") || query.detail.queryType.equals("3"))))) {
                    retAts.RespCode = "-1";
                    retAts.RespInfo = "人行开票后，工商银行自动发起提示承兑，不进行提示承兑以及提示承兑撤回";
                    retAts.WriteBefore();
                    retAts.writeEnd();
                    return retAts;
                }
                retAts.RespCode = "-1";
                retAts.RespInfo = "不支持该查询类型";
                retAts.WriteBefore();
                retAts.writeEnd();
                return retAts;
            }
            bnkVersion = "0.0.0.1";
            bnkfSeqno = bnkPackageID;

            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            bnkTransCode = "QBSINFO";
            //写入ICBC02通用的头部节点
            writeCommonHeader(xmlWriter);

            xmlWriter.writeElementString("BillStat", "");
            xmlWriter.writeElementString("DateType", "");
            xmlWriter.writeElementString("BeginDate", "");
            xmlWriter.writeElementString("EndDate", "");
            xmlWriter.writeElementString("BillNo", "110233201400420160920716956581");
            xmlWriter.writeElementString("AccType", "1");
            xmlWriter.writeElementString("AccNo", query.detail.actNum);
            xmlWriter.writeElementString("MinAmt", "");
            xmlWriter.writeElementString("MaxAmt", "");
            xmlWriter.writeElementString("NextTag", "");
            xmlWriter.writeElementString("ReqReserved1", "");
            xmlWriter.writeElementString("ReqReserved2", "");

            xmlWriter.writeEndDocument();
            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
            if (tmpStrRet[0].length() == 0) {
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/CMS/eb/pub/RetCode");
                    String tmpRetMsg = tmpBkReader.getFirstText("/CMS/eb/pub/RetMsg");
                    if (isActiveRetCode(tmpRetCode)) {
                        retAts.RespCode = "0";
                        retAts.RespInfo = tmpRetMsg;
                        retAts.WriteBefore();
                        while (tmpBkReader.read("/CMS/eb/out/rd")) {
                            RetAtsB001OperBillQryDetail tmpRetDetail = new RetAtsB001OperBillQryDetail();
                            setRetAtsB001OperBillQryDetail(query, tmpRetDetail, tmpBkReader);
                            retAts.writeDetail(tmpRetDetail);
                        }
                    } else {
                        retAts.RespCode = "-1";
                        retAts.RespInfo = tmpRetMsg;
                        retAts.WriteBefore();
                    }
                } else {
                    retAts.RespCode = "-1";
                    retAts.RespInfo = tmpSbMsg.toString();
                    retAts.WriteBefore();
                }
            } else {
                retAts.RespCode = "-1";
                retAts.RespInfo = tmpStrRet[1];
                retAts.WriteBefore();
            }
        } catch (Exception e) {
            retAts.RespCode = "-1";
            retAts.RespInfo = e.getMessage();
            retAts.WriteBefore();
            e.printStackTrace();
        }

        retAts.writeEnd();
        return retAts;
    }*/

    static final Pattern TAG_PAT = Pattern.compile("<\\s*NextTag\\s*>.*?<\\s*/\\s*NextTag\\s*>|<\\s*NextTag\\s*/>");
    public static BijectionHashMap<String, String> OP_TYPE_MAP = new BijectionHashMap<String, String>();
    public static BijectionHashMap<String, String> BILL_TERM_MAP = new BijectionHashMap<String, String>();

    static {
        OP_TYPE_MAP.put("1", "1");
        OP_TYPE_MAP.put("2", "3");

        BILL_TERM_MAP.put("1", "6");
        BILL_TERM_MAP.put("2", "7");
        BILL_TERM_MAP.put("3", "1");
        BILL_TERM_MAP.put("10", "8");
    }

    @Override
    public RetAtsB001OperBillQry D_OperBill_Query_Req(ReqB001OperBillQry query) throws Exception {
        RetAtsB001OperBillQry retAts = new RetAtsB001OperBillQry(query.reqHeader);
//        retAts.writeStart();

        query.readRecord();

        bnkPackageID = query.reqHeader.transSeqID;
        bnkTransCode = B001BusiAndQuery2TransCode(query.detail.busiType, query.detail.queryType);
        if (bnkTransCode == null) {
            if (!StringHelper.isNullOrEmpty(query.detail.busiType) && !StringHelper.isNullOrEmpty(query.detail.queryType)
                    // 1002 提示承兑申请 3002 提示承兑撤回
                    && ((query.detail.busiType.equals("2") && (query.detail.queryType.equals("1") || query.detail.queryType.equals("3"))))) {
                retAts.respCode = "-1";
                retAts.respInfo = "人行开票后，工商银行自动发起提示承兑，不进行提示承兑以及提示承兑撤回";
                retAts.writeBefore();
                retAts.writeEnd();
                return retAts;
            }
            retAts.respCode = "-1";
            retAts.respInfo = "不支持该查询类型";
            retAts.writeBefore();
            retAts.writeEnd();
            return retAts;
        }
        bnkVersion = "0.0.0.1";
        //同意清偿版本为0.0.1.0
//        if (query.detail.busiType.equals("14") && query.detail.queryType.equals("1")) {
//            bnkVersion = "0.0.1.0";
//        }
        bnkfSeqno = bnkPackageID;

        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        //写入ICBC02通用的头部节点
        writeCommonHeader(xmlWriter);

        xmlWriter.writeElementString("OpType", busiAdnQuery2OpType(query.detail.busiType, query.detail.queryType));

//        xmlWriter.writeElementString("DateType", "1");
//        String queryDateStart  = getBankConfig().getValueAsString("queryDateStart");
//        xmlWriter.writeElementString("BeginDate", queryDateStart);
//        String queryDateEnd  = getBankConfig().getValueAsString("queryDateEnd");
//        xmlWriter.writeElementString("EndDate", queryDateEnd);
        xmlWriter.writeElementString("DateType", "");
        xmlWriter.writeElementString("BeginDate", "");
        xmlWriter.writeElementString("EndDate", "");

        xmlWriter.writeElementString("AccNo", query.detail.actNum);
        xmlWriter.writeElementString("MinAmt", "");
        xmlWriter.writeElementString("MaxAmt", "");
        xmlWriter.writeElementString("NextTag", "");
        xmlWriter.writeElementString("ReqReserved1", ELE_BILL_TYPE.get(query.detail.billType));
        xmlWriter.writeElementString("ReqReserved2", query.detail.billNo);

        xmlWriter.writeEndDocument();
        String xml = xmlWriter.toXmlString();
        retAts.writeStart();
        int successCnt = 0;
        try {
            String lastTag = "";
            do {
                lastTag=D_OperBill_Query_Req_TAG(xml, lastTag, query, retAts);
                successCnt++;
            } while (!StringHelper.isNullOrEmpty(lastTag));
            retAts.writeRespCode("0");
        } catch (Exception e) {
            retAts = new RetAtsB001OperBillQry(reqHeader);
            retAts.writeStart();
            retAts.writeRespInfo(e.getMessage());
            retAts.writeRespCode("-1");
        }

        retAts.writeEnd();
        return retAts;
    }
/*
    @Override
    public RetAtsB001OperBillQry D_OperBill_Query_Req(ReqB001OperBillQry query) throws Exception {
        RetAtsB001OperBillQry retAts = new RetAtsB001OperBillQry(query.reqHeader);

        query.readRecord();

        String former = "";
        StringBuilder builder = new StringBuilder();
        do {
            former = searchByTag(former, query, builder);
        } while (!StringHelper.isNullOrEmpty(former));

        synchronized (ICBC02ElecBill.class) {
            File file = new File("D://gonghangData.txt");
            if (!file.exists()) {
                OutputStream os = new FileOutputStream(file);
                os.write(builder.toString().getBytes(Charset.forName("UTF-8")));
                os.close();
            }
        }
        return null;
    }*/

    @Override
    public RetAtsB002BillTransQry D_B002_BillTrans_Query(ReqB002BillTransQry query) throws Exception {
        RetAtsB002BillTransQry retAts = new RetAtsB002BillTransQry(query.reqHeader);

        try {
            bnkPackageID = query.reqHeader.transSeqID;
            bnkTransCode = "QBIINFO";
            bnkfSeqno = bnkPackageID;
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            //写入ICBC02通用的头部节点
            writeCommonHeader(xmlWriter);

            xmlWriter.writeElementString("BillNo", query.billNo);
            xmlWriter.writeElementString("NextTag", "");
            xmlWriter.writeElementString("ReqReserved1", "");
            xmlWriter.writeElementString("ReqReserved2", "");

            xmlWriter.writeEndDocument();
            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/CMS/eb/pub/RetCode");
                    String tmpRetMsg = tmpBkReader.getFirstText("/CMS/eb/pub/RetMsg");
                    if (isActiveRetCode(tmpRetCode)) {
                        retAts.respCode = "0";
                        retAts.respInfo = tmpRetMsg;
                        retAts.writeBefore();
                        while (tmpBkReader.read("/CMS/eb/out/rd")) {
                            RetAtsB002BillTransQryDetail tmpRetDetail = new RetAtsB002BillTransQryDetail();
                            setRetAtsB002BillTransQryDetail(query, tmpRetDetail, tmpBkReader);
                            retAts.writeDetail(tmpRetDetail);
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpRetMsg;
                        retAts.writeBefore();
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                    retAts.writeBefore();
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
                retAts.writeBefore();
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
            retAts.writeBefore();
            e.printStackTrace();
        }
        retAts.writeEnd();
        return retAts;
    }

    @Override
    public RetAtsB004BillFrontQry D_B004_BillFront_Query(ReqB004BillFrontQry query) throws Exception {
        RetAtsB004BillFrontQry retAts = new RetAtsB004BillFrontQry(query.reqHeader);
        retAts.head();
        try {
            bnkPackageID = query.reqHeader.transSeqID;
            bnkTransCode = "QBIINFO";
            bnkfSeqno = bnkPackageID;
            while (query.readRecord()) {
                XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                //写入ICBC02通用的头部节点
                writeCommonHeader(xmlWriter);

                xmlWriter.writeElementString("BillNo", query.detail.billNo);
                xmlWriter.writeElementString("NextTag", "");
                xmlWriter.writeElementString("ReqReserved1", "");
                xmlWriter.writeElementString("ReqReserved2", "");

                xmlWriter.writeEndDocument();
                String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpStrRet[0].length() == 0) {
                    if (tmpBkReader != null) {
                        String tmpRetCode = tmpBkReader.getFirstText("/CMS/eb/pub/RetCode");
                        String tmpRetMsg = tmpBkReader.getFirstText("/CMS/eb/pub/RetMsg");
                        if (isActiveRetCode(tmpRetCode)) {
                            retAts.writeRespCode("0");
                            retAts.writeRespInfo(tmpRetMsg);
                            while (tmpBkReader.read("/CMS/eb/out")) {
                                setRetAtsB004BillFrontQry(query, retAts, tmpBkReader, tmpRetCode, tmpRetMsg);
                                retAts.writeRetDetail();
                            }
                        } else {
                            retAts.writeRespCode("-1");
                            retAts.writeRespInfo(tmpRetMsg);
                        }
                    } else {
                        retAts.writeRespCode("-1");
                        retAts.writeRespInfo(tmpSbMsg.toString());
                    }
                } else {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo(tmpStrRet[1]);
                }
            }
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
            e.printStackTrace();
        }
        retAts.writeAfter();
        return retAts;
    }

    private void setRetAtsB004BillFrontQry(ReqB004BillFrontQry query,
                                           RetAtsB004BillFrontQry tmpRetDetail, XmlTextReader tmpBkReader,
                                           String retCode, String retMsg) throws Exception {
        tmpRetDetail.respCode = "0";
        tmpRetDetail.respInfo = retMsg;

        tmpRetDetail.billNo = tmpBkReader.readedXElement.getSingleText("BillNo");
        tmpRetDetail.billType = convertBillType(tmpBkReader.readedXElement.getSingleText("BillType"));
        tmpRetDetail.issDate = convertDate8(tmpBkReader.readedXElement.getSingleText("BillOpenDate"));
        tmpRetDetail.dueDate = convertDate8(tmpBkReader.readedXElement.getSingleText("BillDueDate"));
        tmpRetDetail.billAmt = StringHelper.amountDivide100(tmpBkReader.readedXElement.getSingleText("BillAmt"));

        tmpRetDetail.transFlag = reciteFlag2TransFlag(tmpBkReader.readedXElement.getSingleText("ReciteFlag"));
//        tmpRetDetail.MustPay = convertMustPay(tmpBkReader.readedXElement.getSingleText("MustPay"));

        tmpRetDetail.drawName = tmpBkReader.readedXElement.getSingleText("BillOpenName");
//        tmpRetDetail.DrawCode = tmpBkReader.readedXElement.getSingleText("DrawCode");
        tmpRetDetail.drawAct = tmpBkReader.readedXElement.getSingleText("BillOpenAcc");
        tmpRetDetail.drawBnkName = tmpBkReader.readedXElement.getSingleText("BillOpenBank");
        tmpRetDetail.drawBnkCode = tmpBkReader.readedXElement.getSingleText("DrawBnkCode");

        tmpRetDetail.creditLv = tmpBkReader.readedXElement.getSingleText("OpenerLevel");
        tmpRetDetail.gradeAgent = tmpBkReader.readedXElement.getSingleText("OpenerCorp");
        tmpRetDetail.gradeDueDate = tmpBkReader.readedXElement.getSingleText("OpenerLvlDt");
        tmpRetDetail.drGuarName = tmpBkReader.readedXElement.getSingleText("OpenEnsureName");
        tmpRetDetail.drGuarAddr = tmpBkReader.readedXElement.getSingleText("OpenEnsureAddr");
        tmpRetDetail.drGuarDate = tmpBkReader.readedXElement.getSingleText("OpenEnsureDate");

        tmpRetDetail.accpName = tmpBkReader.readedXElement.getSingleText("AcceptName");
        tmpRetDetail.accpAct = tmpBkReader.readedXElement.getSingleText("AcceptAccNo");
        tmpRetDetail.accpBnkName = tmpBkReader.readedXElement.getSingleText("AcceptBank");
        tmpRetDetail.accpBnkCode = tmpBkReader.readedXElement.getSingleText("AcceptBankNo");
        tmpRetDetail.accpCredit = tmpBkReader.readedXElement.getSingleText("AcptLevel");
        tmpRetDetail.accpGrade = tmpBkReader.readedXElement.getSingleText("AcptCorp");
        tmpRetDetail.apGuarName = tmpBkReader.readedXElement.getSingleText("AcptLvlDt");

        tmpRetDetail.apGuarName = tmpBkReader.readedXElement.getSingleText("AcptEnsureName");
        tmpRetDetail.apGuarAddr = tmpBkReader.readedXElement.getSingleText("AcptEnsureAddr");
        tmpRetDetail.apGuarDate = tmpBkReader.readedXElement.getSingleText("AcptEnsureDate");

        tmpRetDetail.payeeName = tmpBkReader.readedXElement.getSingleText("RecvAccName");
        tmpRetDetail.payeeAct = tmpBkReader.readedXElement.getSingleText("RecvAccNo");
        tmpRetDetail.payeeBnkName = tmpBkReader.readedXElement.getSingleText("RecvBankName");
//        tmpRetDetail.PayeeBnkCode = tmpBkReader.readedXElement.getSingleText("PayeeBnkCode");

        tmpRetDetail.billState = tmpBkReader.readedXElement.getSingleText("BillState");
    }

    @Override
    public RetAtsB005BillBackQry D_B005_BillBack_Query(ReqB005BillBackQry query) throws Exception {
        RetAtsB005BillBackQry retAts = new RetAtsB005BillBackQry(query.reqHeader);
        retAts.writeBeforeDetail();

        query.readRecord();

        RetAtsB005BillBackQryDetail tmpRetDetail = new RetAtsB005BillBackQryDetail();
        bnkPackageID = query.reqHeader.transSeqID;
        bnkTransCode = "QBIINFO";
        bnkfSeqno = bnkPackageID;
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        //写入ICBC02通用的头部节点
        writeCommonHeader(xmlWriter);

        xmlWriter.writeElementString("BillNo", query.detail.billNo);
        xmlWriter.writeElementString("NextTag", "");
        xmlWriter.writeElementString("ReqReserved1", "");
        xmlWriter.writeElementString("ReqReserved2", "");

        xmlWriter.writeEndDocument();
        String xml = xmlWriter.toXmlString();

        int successCnt = 0;
        try {
            String lastTag = "";
            do {
                D_B005_BillBack_Query_TAG(xml, lastTag, query, retAts);
                successCnt++;
            } while (!StringHelper.isNullOrEmpty(lastTag));
            retAts.writeRespCode("0");
        } catch (Exception e) {
            retAts.writeRespInfo(e.getMessage());
            if (successCnt == 0) {
                retAts.writeRespCode("-1");
            } else {
                retAts.writeRespCode("0");
            }
        }

        retAts.writeAfter();
        return retAts;
    }

    public String D_B005_BillBack_Query_TAG(String xml, String tag, ReqB005BillBackQry query, RetAtsB005BillBackQry retAts) throws Exception {
        xml = TAG_PAT.matcher(xml).replaceAll("<NextTag>" + tag + "</NextTag>");

        String[] tmpStrRet = sendToBank(xml);
        StringBuilder tmpSbMsg = new StringBuilder();
        XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);

        String nextTag = null;
        if (tmpStrRet[0].length() == 0) {
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/CMS/eb/pub/RetCode");
                String tmpRetMsg = tmpBkReader.getFirstText("/CMS/eb/pub/RetMsg");
                if (isActiveRetCode(tmpRetCode)) {
                    nextTag = tmpBkReader.getFirstText("/CMS/eb/out/NextTag");
                    while (tmpBkReader.read("/CMS/eb/out/rd")) {
                        RetAtsB005BillBackQryDetail queryDetail = new RetAtsB005BillBackQryDetail();
                        setRetAtsB005BillBackQryDetail(query, queryDetail, tmpBkReader, tmpRetCode, tmpRetMsg);
                        retAts.writeDetail(queryDetail);
                    }
                } else {
                    throw new Exception(tmpRetMsg);
                }
            } else {
                throw new Exception(tmpSbMsg.toString());
            }
        } else {
            throw new Exception(tmpStrRet[1]);
        }
        return nextTag;
    }

    private void setRetAtsB005BillBackQryDetail(ReqB005BillBackQry query,
                                                RetAtsB005BillBackQryDetail tmpRetDetail, XmlTextReader tmpBkReader,
                                                String retCode, String retMsg) throws Exception {
        tmpRetDetail.respCode = "0";
        tmpRetDetail.respInfo = retMsg;

        tmpRetDetail.billNo = tmpBkReader.readedXElement.getSingleText("BillNo");
        String tranType = convertTransCode(tmpBkReader.readedXElement.getSingleText("TranType"));
        if (tranType == null) {
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = "票据背面查询操作类型转换错误";
        }
        tmpRetDetail.transCode = tranType;
        tmpRetDetail.applyName = tmpBkReader.readedXElement.getSingleText("AccName");
        tmpRetDetail.receName = tmpBkReader.readedXElement.getSingleText("NextAccName");
//        tmpRetDetail.ApplyDate = tmpBkReader.readedXElement.getSingleText("ApplyDate");
        //YYYY-MM-DD 转为 yyyy-MM-dd HH:mm:ss
        String applyOrResp = getBankConfig().getValueAsString("ApplyOrResp");
        if(StringHelper.hasAnyChar(applyOrResp)&&applyOrResp.toLowerCase().equals("apply")) {
            tmpRetDetail.applyDate = tmpBkReader.readedXElement.getSingleText("SignDate");
        }else{
            tmpRetDetail.respDate = tmpBkReader.readedXElement.getSingleText("SignDate");
        }
        tmpRetDetail.transFlag = reciteFlag2TransFlag(tmpBkReader.readedXElement.getSingleText("ReciteFlag"));
        tmpRetDetail.guarAddr = tmpBkReader.readedXElement.getSingleText("RepReserved5");
//        tmpRetDetail.RepOpenDate = tmpBkReader.readedXElement.getSingleText("RepOpenDate");
//        tmpRetDetail.RepDueDate = tmpBkReader.readedXElement.getSingleText("RepDueDate");
//        tmpRetDetail.RespFlag = tmpBkReader.readedXElement.getSingleText("RespFlag");
//        tmpRetDetail.UnPayCode = tmpBkReader.readedXElement.getSingleText("UnPayCode");
//        tmpRetDetail.RecourseType = tmpBkReader.readedXElement.getSingleText("RecourseType");
    }

    /**
     * bank → ats
     * <p>
     * bank 1-背书转让  2-保证  3-贴现  4-质押  5-贴现赎回  6-追索  7-清偿
     * ats 参考 EledraftsOfBankServiceImpl#getDraftBackTransName
     * 2-承兑 3-收票 4-撤票 10-背书转让 11-贴现 12-回购式贴现赎回
     * 13-转贴现 14-回购式转贴现赎回 15-再贴现 16-回购式再贴现赎回 25-央行卖出商业汇票 17-保证 18-质押 19-质押解除 20-提示付款
     * 21-逾期提示付款 22-追索 23-追索同意清偿
     *
     * @param tranType
     * @return
     */
    private String convertTransCode(String tranType) {
        if (StringHelper.isNullOrEmpty(tranType)) return null;
        int tranValue = Integer.parseInt(tranType);
        switch (tranValue) {
            case 1:
                return "10";
            case 2:
                return "17";
            case 3:
                return "11";
            case 4:
                return "18";
            case 5:
                return "12";
            case 6:
                return "22";
            case 7:
                return "23";
        }
        return null;
    }

    @Override
    public RetAtsB006BillStateQry D_B006_BillState_Qeury(ReqB006BillStateQry query) throws Exception {
        RetAtsB006BillStateQry retAts = new RetAtsB006BillStateQry(query.reqHeader);
        retAts.writeBeforeDetail();

        while (query.readRecord()) {
            RetAtsB006BillStateQryDetail tmpRetDetail = new RetAtsB006BillStateQryDetail();
            try {
                bnkPackageID = query.reqHeader.transSeqID;
                bnkTransCode = B006BusiAndOper2TransCode(query.detail.busiType, query.detail.operType, query.detail.billType);
                if (bnkTransCode == null) {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = "不支持该操作指令查询";
                    retAts.writeDetail(tmpRetDetail);
                    continue;
                }
                bnkfSeqno = bnkPackageID;
                XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                //写入ICBC02通用的头部节点
                writeCommonHeader(xmlWriter);

                setB006SendXMLWriter(xmlWriter, query);

                xmlWriter.writeEndDocument();
                String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String tmpRetCode = tmpBkReader.getFirstText("/CMS/eb/pub/RetCode");
                        String tmpRetMsg = tmpBkReader.getFirstText("/CMS/eb/pub/RetMsg");
                        if (isActiveRetCode(tmpRetCode) || "B0116".equals(tmpRetCode)) {    //增加无操作记录的处理
                            if (bnkTransCode.equals("QBIMPAWN")
                                    //解质押申请
                                    || bnkTransCode.equals("QBDISIMP")
                                    //出票保证、承兑保证、背书保证
                                    //追索申请
                                    || bnkTransCode.equals("QBRECOURSE")
                                    //同意清偿申请
                                    || bnkTransCode.equals("QBAGRSTLM")
                                    //提示承兑签收
                                    || bnkTransCode.equals("QBSACPT")
                                    //质押签收
                                    || bnkTransCode.equals("QSIGNBPLED")
                                    //解质押签收
                                    || bnkTransCode.equals("QRELSIGNBP")
                                    //出票保证签收、承兑保证签收、质押保证签收
                                    || bnkTransCode.equals("QBSGUAR")
                                    //同意清偿签收
                                    || bnkTransCode.equals("QBSIGNASTL")
                                    //质押撤回
                                    || bnkTransCode.equals("QWDBPLED")
                                    //质押解除撤回
                                    || bnkTransCode.equals("QRELWBPLE")
                                    //出票保证撤回、承兑保证撤回、背书保证撤回
                                    || bnkTransCode.equals("QBCGUAR")
                                    //追索通知撤回
                                    || bnkTransCode.equals("QWDBRECOU")
                                    //同意清偿撤回
                                    || bnkTransCode.equals("QRELBAST")
                                    ) {
                                //对应高级查询接口
                                tmpBkReader.read("/CMS/eb/out/rd");
                            } else {
                                tmpBkReader.read("/CMS/eb/out");
                            }
                            setRetAtsB006BillStateQryDetail(query, tmpRetDetail, tmpBkReader, tmpRetCode, tmpRetMsg);
                            retAts.writeDetail(tmpRetDetail);
                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = tmpBkReader.getFirstText("/CMS/eb/pub/RetMsg");
                            retAts.writeDetail(tmpRetDetail);
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpSbMsg.toString();
                        retAts.writeDetail(tmpRetDetail);
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpStrRet[1];
                    retAts.writeDetail(tmpRetDetail);
                }
            } catch (Exception e) {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = e.getMessage();
                retAts.writeDetail(tmpRetDetail);
                e.printStackTrace();
            }
        }
        retAts.writeEnd();
        return retAts;
    }

    /**
     * ats → bank
     *
     * @param busiType
     * @param queryType
     * @return
     */
    private String B006BusiAndOper2TransCode(String busiType, String queryType, String billType) {
        if (StringHelper.isNullOrEmpty(busiType) || StringHelper.isNullOrEmpty(queryType) || StringHelper.isNullOrEmpty(billType)) {
            return null;
        }
        int busi = Integer.parseInt(busiType);
        int query = Integer.parseInt(queryType);
        switch (query) {
            //1-待操作
            case 1:
                switch (busi) {
                    //1001-出票登记申请
                    case 1:
                        //票据类型 1-银承 2-商承
                        if (billType.equals("1")) {
                            return "QBIBANK";
                        }
                        if (billType.equals("2")) {
                            return "QBICORP";
                        }
                        return null;
                    //1002-提示承兑申请
                    case 2:
                        return null;
                    //1003-提示收票申请
                    case 3:
                        return "QBIPCOL";
                    //1004-背书转让申请
                    case 4:
                        return "QBIENDO";
                    //1005-质押申请
                    case 5:
                        return "QBIMPAWN";
                    //1006-可质押解除申请
                    case 6:
                        return "QBDISIMP";
                    //1007-出票保证申请
                    case 7:
                        return "QBIGUAR";
                    //1008-承兑保证申请
                    case 8:
                        return "QBIGUAR";
                    //1009-背书保证申请
                    case 9:
                        return "QBIGUAR";
                    //1010-贴现申请
                    case 10:
                        return "QBIDISC";
                    //1011-可回购式贴现赎回
                    case 11:
                        return "QBRDISC";
                    //1012-提示付款申请
                    case 12:
                        return "QBIPPAY";
                    //1013-追索通知申请
                    case 13:
                        return "QBRECOURSE";
                    //1014-同意清偿申请
                    case 14:
                        return "QBAGRSTLM";
                }
                break;
            //2-待应答
            case 2:
            case 3:
                switch (busi) {
                    case 1:
                        return null;
                    //2002-提示承兑签收
                    case 2:
                        return "QBSACPT";
                    //2003-提示收票签收
                    case 3:
                        return "QBSPCOL";
                    //2004-背书转让签收
                    case 4:
                        return "QBSENDO";
                    //2005-质押签收
                    case 5:
                        return "QSIGNBPLED";
                    //2006-质押解除签收
                    case 6:
                        return "QRELSIGNBP";
                    //2007-出票保证签收
                    case 7:
                        return "QBSGUAR";
                    //2008-承兑保证签收
                    case 8:
                        return "QBSGUAR";
                    //2009-背书保证签收
                    case 9:
                        return "QBSGUAR";
                    //2010-贴现申请签收
                    case 10:
                        return null;
                    //2011-回购式贴现赎回签收
                    case 11:
                        return "QBSDISC";
                    //2012-提示付款签收
                    case 12:
                        return "QBSPPAY";
                    //2013-追索签收
                    case 13:
                        return null;
                    //2014-同意清偿签收
                    case 14:
                        return "QBSIGNASTL";
                }
                break;
            //4-待撤回
            case 4:
                switch (busi) {
                    //3001-撤票
                    case 1:
                        return "QBCBILL";
                    //3002-提示承兑撤回
                    case 2:
                        return null;
                    //3003-提示收票撤回
                    case 3:
                        return "QBCPCOL";
                    //3004-背书转让撤回
                    case 4:
                        return "QBCENDO";
                    //3005-质押撤回
                    case 5:
                        return "QWDBPLED";
                    //3006-解质押撤回
                    case 6:
                        return "QRELWBPLE";
                    //3007-出票保证撤回
                    case 7:
                        return "QBCGUAR";
                    //3008-承兑保证撤回
                    case 8:
                        return "QBCGUAR";
                    //3009-背书保证撤回
                    case 9:
                        return "QBCGUAR";
                    //3010-贴现撤回
                    case 10:
                        return "QBCDISC";
                    //3011-回购式贴现赎回撤回
                    case 11:
                        return null;
                    //3012-提示付款撤回
                    case 12:
                        return "QBCPPAY";
                    //3013-追索通知撤回
                    case 13:
                        return "QWDBRECOU";
                    //3014-同意清偿撤回
                    case 14:
                        return "QRELBAST";
                }
                break;
        }
        return null;
    }

    /**
     * 设置发送至银行的报文
     * 目前有3种格式,对应bnkVersion也存在不同,查找时,请直接查询对应操作名称
     *
     * @param xmlWriter
     * @param query
     */
    private void setB006SendXMLWriter(XmlTextWriter xmlWriter, ReqB006BillStateQry query) {
        //出票申请
        if (bnkTransCode.equals("QBIBANK") || bnkTransCode.equals("QBICORP")) {
            bnkVersion = "0.0.1.0";
            xmlWriter.writeElementString("QryfSeqno", "");
            xmlWriter.writeElementString("QrySerialNo", query.detail.reqSeqID);
            xmlWriter.writeElementString("RefNo", "");
            //提示收票
        } else if (bnkTransCode.equals("QBIPCOL")
                //背书转让
                || bnkTransCode.equals("QBIENDO")
                //贴现申请
                || bnkTransCode.equals("QBIDISC")
                //回购式贴现赎回
                || bnkTransCode.equals("QBRDISC")
                //提示付款
                || bnkTransCode.equals("QBIPPAY")
                //提示收票签收
                || bnkTransCode.equals("QBSPCOL")
                //背书转让签收
                || bnkTransCode.equals("QBSENDO")
                //回购式贴现签收赎回
                || bnkTransCode.equals("QBSDISC")
                //提示付款签收
                || bnkTransCode.equals("QBSPPAY")
                //撤票
                || bnkTransCode.equals("QBCBILL")
                //提示收票撤回
                || bnkTransCode.equals("QBCPCOL")
                //背书转让撤回
                || bnkTransCode.equals("QBCENDO")
                //贴现撤回
                || bnkTransCode.equals("QBCDISC")
                //提示付款撤回
                || bnkTransCode.equals("QBCPPAY")
                ) {
            bnkVersion = "0.0.0.1";
            xmlWriter.writeElementString("QryfSeqno", "");
            xmlWriter.writeElementString("QrySerialNo", query.detail.reqSeqID);
            xmlWriter.writeElementString("ReqReserved1", "");
            xmlWriter.writeElementString("ReqReserved2", "");
        }
        //质押申请
        else if (bnkTransCode.equals("QBIMPAWN")
                //解质押申请
                || bnkTransCode.equals("QBDISIMP")
                //出票保证、承兑保证、背书保证
                //追索申请
                || bnkTransCode.equals("QBRECOURSE")
                //同意清偿申请
                || bnkTransCode.equals("QBAGRSTLM")
                //提示承兑签收
                || bnkTransCode.equals("QBSACPT")
                //质押签收
                || bnkTransCode.equals("QSIGNBPLED")
                //解质押签收
                || bnkTransCode.equals("QRELSIGNBP")
                //出票保证签收、承兑保证签收、质押保证签收
                || bnkTransCode.equals("QBSGUAR")
                //同意清偿签收
                || bnkTransCode.equals("QBSIGNASTL")
                //质押撤回
                || bnkTransCode.equals("QWDBPLED")
                //质押解除撤回
                || bnkTransCode.equals("QRELWBPLE")
                //出票保证撤回、承兑保证撤回、背书保证撤回
                || bnkTransCode.equals("QBCGUAR")
                //追索通知撤回
                || bnkTransCode.equals("QWDBRECOU")
                //同意清偿撤回
                || bnkTransCode.equals("QRELBAST")
                ) {
            bnkVersion = "0.0.1.0";
            xmlWriter.writeElementString("QryfSeqno", "");
            xmlWriter.writeElementString("QrySerialno", query.detail.reqSeqID);
        }
    }

    private void setRetAtsB006BillStateQryDetail(ReqB006BillStateQry query,
                                                 RetAtsB006BillStateQryDetail tmpRetDetail, XmlTextReader tmpBkReader,
                                                 String retCode, String retMsg) throws Exception {
        String result = tmpBkReader.readedXElement.getSingleText("Result");
        XmlTextReader reader = null;
        if(!StringHelper.isNullOrEmpty(result)) {
            tmpRetDetail.respCode = "0";
            tmpRetDetail.respInfo = tmpBkReader.readedXElement.getSingleText("iRetMsg");
            //当申请类交易返回17结果码，代表已撤销
            if("17".equals(result)&&StringHelper.isNullOrEmpty(tmpRetDetail.respInfo)){
                tmpRetDetail.respInfo="交易已撤销";
            }
            if(StringHelper.isNullOrEmpty(tmpRetDetail.respInfo)){
                tmpRetDetail.respInfo = retMsg;
            }

            tmpRetDetail.billNo = tmpBkReader.readedXElement.getSingleText("BillNo");
            tmpRetDetail.reqSeqID = tmpBkReader.readedXElement.getSingleText("QryfSeqno");
            tmpRetDetail.payInfoCode = tmpBkReader.readedXElement.getSingleText("iRetCode");
            //tmpRetDetail.BillState = completeOperType(query.detail.BusiType, query.detail.OperType) + "+" + result;
            tmpRetDetail.busiNo = tmpBkReader.readedXElement.getSingleText("QrySerialNo");
            if(StringHelper.hasAnyChar(tmpRetDetail.billNo)) {
                reader = QBIINFO(tmpRetDetail.billNo, Format.DateTime17SSSFormat.format(new Date()));
                if (reader != null) {
                    tmpRetDetail.billState = reader.getFirstText("/CMS/eb/out/BillState");
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = "获取票据状态失败";
                }
            }
            if("7".equals(result)&&"1".equals(query.detail.busiType)&&"4".equals(query.detail.operType)) {
                if("000002".equals(tmpRetDetail.billState)) {
                    tmpRetDetail.transState = "BCBILL+" + result;
                }else{
                    tmpRetDetail.transState =result;
                }
            }else{
                tmpRetDetail.transState =result;
            }
        }
        //增加result为空(记录不存在)的判断
        else{
            tmpRetDetail.respCode = "0";
            tmpRetDetail.respInfo = retMsg;

            tmpRetDetail.billNo = query.detail.billNo;
            tmpRetDetail.reqSeqID = query.detail.reqSeqID;  //待查询指令包序列号
            tmpRetDetail.transState = retCode;   //对应查询为空，操作失败
            tmpRetDetail.payInfoCode = retCode;
            tmpRetDetail.busiNo = tmpBkReader.readedXElement.getSingleText("QrySerialNo");

            reader = QBIINFO(tmpRetDetail.billNo, Format.DateTime17SSSFormat.format(new Date()));

            if (reader != null) {
                tmpRetDetail.billState = reader.getFirstText("/CMS/eb/out/BillState");
            }else{
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "获取票据状态失败";
            }
        }
    }

    public XmlTextReader QBIINFO(String billNo, String transSeqID) throws Exception {
        bnkPackageID = transSeqID;
        bnkTransCode = "QBIINFO";
        bnkfSeqno = bnkPackageID;
        bnkVersion = "0.0.0.1";
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        //写入ICBC02通用的头部节点
        writeCommonHeader(xmlWriter);

        xmlWriter.writeElementString("BillNo", billNo);
        xmlWriter.writeElementString("NextTag", "");
        xmlWriter.writeElementString("ReqReserved1", "");
        xmlWriter.writeElementString("ReqReserved2", "");

        xmlWriter.writeEndDocument();
        String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
        StringBuilder tmpSbMsg = new StringBuilder();
        XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
        if (tmpStrRet[0].length() == 0) {
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/CMS/eb/pub/RetCode");
                String tmpRetMsg = tmpBkReader.getFirstText("/CMS/eb/pub/RetMsg");
                if (isActiveRetCode(tmpRetCode)) {
                    return tmpBkReader;
                } else {
                }
            } else {
            }
        } else {
        }
        return null;
    }

    @Override
    public RetAtsB007BillKzsrQry D_B007_BillKzsr_Query(ReqB007BillKzsrQry query) throws Exception {
        RetAtsB007BillKzsrQry retAts = new RetAtsB007BillKzsrQry(query.reqHeader);
        retAts.writeBeforeDetail();

        bnkPackageID = query.reqHeader.transSeqID;
        bnkVersion = "0.0.0.1";
        bnkfSeqno = bnkPackageID;

        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        bnkTransCode = "QBIINFO";
        //写入ICBC02通用的头部节点
        writeCommonHeader(xmlWriter);

        query.readRecord();
        xmlWriter.writeElementString("BillNo", query.detail.billNo);
        xmlWriter.writeElementString("NextTag", "");
        xmlWriter.writeElementString("ReqReserved1", query.detail.actNum);
        xmlWriter.writeElementString("ReqReserved2", "");
        xmlWriter.writeEndDocument();

        String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
        StringBuilder tmpSbMsg = new StringBuilder();
        XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);

        String billState;
        if (tmpStrRet[0].length() == 0) {
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/CMS/eb/pub/RetCode");
                String tmpRetMsg = tmpBkReader.getFirstText("/CMS/eb/pub/RetMsg");
                if (isActiveRetCode(tmpRetCode)) {
                    billState = tmpBkReader.getFirstText("/CMS/eb/out/BillState");
                    String billType = tmpBkReader.getFirstText("/CMS/eb/out/BillType");

                    //没有开户行编码，所以不返回
                    RetAtsB007BillKzsrQryDetail openGuy = new RetAtsB007BillKzsrQryDetail();
                    openGuy.receBnkName = tmpBkReader.getFirstText("/CMS/eb/out/BillOpenBank"); //出票人银行名称
                    openGuy.receBnkCode =query.detail.billNo.substring(1,13);//票据的2到13位是出票人开户行号
                    openGuy.receAct = tmpBkReader.getFirstText("/CMS/eb/out/BillOpenAcc"); //出票人账号
                    openGuy.receName = tmpBkReader.getFirstText("/CMS/eb/out/BillOpenName");//出票人名称
                    retAts.writeDetail(openGuy);

                    //承兑人
                    if("AC02".equals(billType)) {
                        RetAtsB007BillKzsrQryDetail acceptor = new RetAtsB007BillKzsrQryDetail();
                        acceptor.receName = tmpBkReader.getFirstText("/CMS/eb/out/AcceptName"); ///CMS/eb/out/rd/AcceptName	承兑人/承兑行名称
                        acceptor.receBnkName = tmpBkReader.getFirstText("/CMS/eb/out/AcceptBank"); ///CMS/eb/out/rd/AcceptBank	承兑人银行名称
                        acceptor.receBnkCode = tmpBkReader.getFirstText("/CMS/eb/out/AcceptBankNo");///CMS/eb/out/rd/AcceptBankNo	承兑行行号/承兑人开户行行号
                        acceptor.receAct = tmpBkReader.getFirstText("/CMS/eb/out/AcceptAccNo");///CMS/eb/out/rd/AcceptAccNo	承兑人账号
                        retAts.writeDetail(acceptor);
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpRetMsg;
                    retAts.writeAfter();
                    return retAts;
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[0];
                retAts.writeAfter();
                return retAts;
            }
        } else {
            retAts.respCode = "-1";
            retAts.respInfo = tmpStrRet[0];
            retAts.writeAfter();
            return retAts;
        }


        //根据票据状态判断可追索人
        //'210312','逾期提示付款已拒付（可拒付追索，只能追出票人，承兑人及其保证人）
        //'200312','提示付款已拒付（可拒付追索，只能追出票人，承兑人及其保证人）'
        if (!Arrays.asList("210312", "200312").contains(billState)) {
            String xml = xmlWriter.toXmlString();

            //查询所有前手，并作为追索人返回
            int successCnt = 0;
            try {
                String lastTag = "";
                do {
                    D_B007_BillKzsr_Query_TAG(xml, lastTag, query, retAts);
                    successCnt++;
                } while (!StringHelper.isNullOrEmpty(lastTag));
                retAts.writeRespCode("0");
            } catch (Exception e) {
                retAts.writeRespInfo(e.getMessage());
                if (successCnt == 0) {
                    retAts.writeRespCode("-1");
                } else {
                    retAts.writeRespCode("0");
                }
            }
        }

        retAts.writeEnd();
        return retAts;
    }

    @Override
    public RetAtsB008HistoricalBillQry D_B008_HistoricalBillQuery(ReqB008HistoricalBillQry query) throws Exception {
        RetAtsB008HistoricalBillQry result = new RetAtsB008HistoricalBillQry(reqHeader);
        result.respCode = "-1";
        result.respInfo = "DSP未实现接口";
        result.writeBefore();
        result.writeAfter();
        return result;

    }

    @Override
    public RetAtsB009DrawBillQry D_B009_DrawBillQuery(ReqB009DrawBillQry query) throws Exception {
        return null;
    }

    @Override
    public RetAtsB010ProtocolStateQry D_B010_ProtocolStateQuery(ReqB010ProtocolStateQry query) throws Exception {
        return null;
    }

    @Override
    public RetAtsB011TransFlagQry D_B011_TransFlagQuery(ReqB011TransFlagQry query) throws Exception {
        return null;
    }

    public String D_B007_BillKzsr_Query_TAG(String xml, String tag, ReqB007BillKzsrQry query, RetAtsB007BillKzsrQry retAts) throws Exception {
        xml = TAG_PAT.matcher(xml).replaceAll("<NextTag>" + tag + "</NextTag>");

        String[] tmpStrRet = sendToBank(xml);
        StringBuilder tmpSbMsg = new StringBuilder();
        XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);

        String nextTag = null;
        if (tmpStrRet[0].length() == 0) {
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/CMS/eb/pub/RetCode");
                String tmpRetMsg = tmpBkReader.getFirstText("/CMS/eb/pub/RetMsg");
                if (isActiveRetCode(tmpRetCode)) {
                    nextTag = tmpBkReader.getFirstText("/CMS/eb/out/NextTag");
                    while (tmpBkReader.read("/CMS/eb/out/rd")) {
                        String transType = tmpBkReader.readedXElement.getSingleText("TranType");
                        if (StringHelper.isNullOrEmpty(transType)) {
                            continue;
                        }
                        switch (Integer.parseInt(transType)) {
                            case 1:
                            case 2: {
                                RetAtsB007BillKzsrQryDetail former = new RetAtsB007BillKzsrQryDetail();
                                former.receName = tmpBkReader.readedXElement.getSingleText("AccName"); ///CMS/eb/out/rd/AccName	交易前手名称
                                former.receAct = tmpBkReader.readedXElement.getSingleText("AccNo"); ///CMS/eb/out/rd/AccNo	交易前手账号
                                former.receBnkCode = tmpBkReader.readedXElement.getSingleText("AccBank"); ///CMS/eb/out/rd/AccBank	交易前手开户银行
                                retAts.writeDetail(former);
                            }
                            break;
                        }
                    }
                } else {
                    throw new Exception(tmpRetMsg);
                }
            } else {
                throw new Exception(tmpSbMsg.toString());
            }
        } else {
            throw new Exception(tmpStrRet[1]);
        }
        return nextTag;
    }

    private void setRetAtsB002BillTransQryDetail(ReqB002BillTransQry query, RetAtsB002BillTransQryDetail tmpRetDetail, XmlTextReader tmpBkReader) throws Exception {
        tmpRetDetail.billNo = tmpBkReader.readedXElement.getSingleText("BillNo");
        tmpRetDetail.billType = convertBillType(tmpBkReader.readedXElement.getSingleText("BillType"));
        tmpRetDetail.busiType = query.busiType;
        tmpRetDetail.queryType = query.queryType;
        tmpRetDetail.transFlag = reciteFlag2TransFlag(tmpBkReader.readedXElement.getSingleText("ReciteFlag"));

//        tmpRetDetail.applyDate = tmpBkReader.readedXElement.getSingleText("applyDate");
//        tmpRetDetail.respDate = tmpBkReader.readedXElement.getSingleText("respDate");
//        tmpRetDetail.applyCode = tmpBkReader.readedXElement.getSingleText("applyCode");
//        tmpRetDetail.applyAct = tmpBkReader.readedXElement.getSingleText("applyAct");
//        tmpRetDetail.applyBnkName = tmpBkReader.readedXElement.getSingleText("applyBnkName");
//        tmpRetDetail.applyBnkCode = tmpBkReader.readedXElement.getSingleText("applyBnkCode");

        tmpRetDetail.receName = tmpBkReader.readedXElement.getSingleText("RecvAccName");
//        tmpRetDetail.receCode = tmpBkReader.readedXElement.getSingleText("receCode");
        tmpRetDetail.receAct = tmpBkReader.readedXElement.getSingleText("RecvAccNo");
        tmpRetDetail.receBnkName = tmpBkReader.readedXElement.getSingleText("RecvBankName");
//        tmpRetDetail.receBnkCode = tmpBkReader.readedXElement.getSingleText("receBnkCode");

        tmpRetDetail.memo = tmpBkReader.readedXElement.getSingleText("Remark");
        tmpRetDetail.contractNo = tmpBkReader.readedXElement.getSingleText("ContractNo");
        tmpRetDetail.invoiceNo = tmpBkReader.readedXElement.getSingleText("InvoiceNo");
        tmpRetDetail.guarAddr = tmpBkReader.readedXElement.getSingleText("RepReserved5");

//        tmpRetDetail.discType = tmpBkReader.readedXElement.getSingleText("discType");
//        tmpRetDetail.payType = tmpBkReader.readedXElement.getSingleText("payType");
//        tmpRetDetail.repOpenDate = tmpBkReader.readedXElement.getSingleText("repOpenDate");
//        tmpRetDetail.repDueDate = tmpBkReader.readedXElement.getSingleText("repDueDate");
//        tmpRetDetail.discRate = tmpBkReader.readedXElement.getSingleText("discRate");
//        tmpRetDetail.discAmt = tmpBkReader.readedXElement.getSingleText("discAmt");
//        tmpRetDetail.repRate = tmpBkReader.readedXElement.getSingleText("repRate");
//        tmpRetDetail.repAmt = tmpBkReader.readedXElement.getSingleText("repAmt");
//        tmpRetDetail.proPayAmt = tmpBkReader.readedXElement.getSingleText("proPayAmt");
//        tmpRetDetail.actedAct = tmpBkReader.readedXElement.getSingleText("actedAct");
//        tmpRetDetail.actedBnkCode = tmpBkReader.readedXElement.getSingleText("actedBnkCode");
//        tmpRetDetail.unPayCode = tmpBkReader.readedXElement.getSingleText("unPayCode");
//        tmpRetDetail.guarType = tmpBkReader.readedXElement.getSingleText("guarType");
//        tmpRetDetail.overDueRea = tmpBkReader.readedXElement.getSingleText("overDueRea");
//        tmpRetDetail.recourseType = tmpBkReader.readedXElement.getSingleText("recourseType");
//        tmpRetDetail.recourseAmt = tmpBkReader.readedXElement.getSingleText("recourseAmt");
//        tmpRetDetail.recourseCode = tmpBkReader.readedXElement.getSingleText("recourseCode");
    }

    /**
     * B001 可操作票据查询
     * 根据ats报文,获取TransCode
     * <p>
     * 参数参考 EledraftsOfBankServiceImpl#QueryHistoryEledrafts 方法中的说明
     * 转换参数 - 根据excel 票据查询接口-票据操作信息查询
     *
     * @param busiType  1-出票 2-承兑 3-收票 4-背书转让 5-质押 6-解质押 7-出票保证 8-承兑保证 9-背书保证 10-贴现 11-回购式贴现赎回 12-提示付款 13-追索 14-同意清偿
     * @param queryType 1-待操作 2-待应答 3-待撤回
     * @return
     */
    private String B001BusiAndQuery2TransCode(String busiType, String queryType) {
        if (StringHelper.isNullOrEmpty(busiType) || StringHelper.isNullOrEmpty(queryType)) {
            return null;
        }
        int busi = Integer.parseInt(busiType);
        int query = Integer.parseInt(queryType);
        switch (query) {
            //1-待操作
            case 1:
                switch (busi) {
                    //1001-出票登记申请
                    case 1:
                        return null;
                    //1002-提示承兑申请
                    case 2:
                        return null;
                    //1003-提示收票申请
                    case 3:
                        return "QBPCOLL";
                    //1004-背书转让申请
                    case 4:
                        return "QBENDOL";
                    //1005-质押申请
                    case 5:
                        return "QBIMPL";
                    //1006-可质押解除申请
                    case 6:
                        return "QBRELIMP";
                    //1007-出票保证申请
                    case 7:
                        return "QBGUARL";
                    //1008-承兑保证申请
                    case 8:
                        return "QBGUARL";
                    //1009-背书保证申请
                    case 9:
                        return "QBGUARL";
                    //1010-贴现申请
                    case 10:
                        return "QBDISCL";
                    //1011-可回购式贴现赎回
                    case 11:
                        return "QBDISCR";
                    //1012-提示付款申请
                    case 12:
                        return "QBPPAYL";
                    //1013-追索通知申请
                    case 13:
                        return "QBRCURS";
                    //1014-同意清偿申请
                    case 14:
                        return "QBDSCRG";
                }
                break;
            //2-待应答
            case 2:
                switch (busi) {
                    case 1:
                        return null;
                    //2002-提示承兑签收
                    case 2:
                        return "QBACPTL";
                    //2003-提示收票签收
                    case 3:
                        return "QBPCOLS";
                    //2004-背书转让签收
                    case 4:
                        return "QBENDOS";
                    //2005-质押签收
                    case 5:
                        return "QBSGNIMP";
                    //2006-质押解除签收
                    case 6:
                        return "QBSGNRIMP";
                    //2007-出票保证签收
                    case 7:
                        return "QBGUARS";
                    //2008-承兑保证签收
                    case 8:
                        return "QBGUARS";
                    //2009-背书保证签收
                    case 9:
                        return "QBGUARS";
                    //2010-贴现申请签收
                    case 10:
                        return null;
                    //2011-回购式贴现赎回签收
                    case 11:
                        return "QBDISCS";
                    //2012-提示付款签收
                    case 12:
                        return "QBPPAYS";
                    //2013-追索签收
                    case 13:
                        return null;
                    //2014-同意清偿签收
                    case 14:
                        return "QBSGNDSCRG";
                }
                break;
            //3-待撤回
            case 3:
                switch (busi) {
                    //3001-撤票
                    case 1:
                        return "QBBILLC";
                    //3002-提示承兑撤回
                    case 2:
                        return null;
                    //3003-提示收票撤回
                    case 3:
                        return "QBPCOLC";
                    //3004-背书转让撤回
                    case 4:
                        return "QBENDOC";
                    //3005-质押撤回
                    case 5:
                        return "QBWDIMP";
                    //3006-解质押撤回
                    case 6:
                        return "QBWDRIMP";
                    //3007-出票保证撤回
                    case 7:
                        return "QBGUARC";
                    //3008-承兑保证撤回
                    case 8:
                        return "QBGUARC";
                    //3009-背书保证撤回
                    case 9:
                        return "QBGUARC";
                    //3010-贴现撤回
                    case 10:
                        return "QBDISCC";
                    //3011-回购式贴现赎回撤回
                    case 11:
                        return null;
                    //3012-提示付款撤回
                    case 12:
                        return "QBPPAYC";
                    //3013-追索通知撤回
                    case 13:
                        return "QBWDRCURS";
                    //3014-同意清偿撤回
                    case 14:
                        return "QBWDDSCRG";
                }
                break;
        }
        return null;
    }

    /**
     * B001 可操作票据查询
     * 根据ats报文,获取opType
     * <p>
     * 参数参考 EledraftsOfBankServiceImpl#QueryHistoryEledrafts 方法中的说明
     * 转换参数 - 根据excel 票据查询接口-票据操作信息查询
     *
     * @param busiType  1-出票 2-承兑 3-收票 4-背书转让 5-质押 6-解质押 7-出票保证 8-承兑保证 9-背书保证 10-贴现 11-回购式贴现赎回 12-提示付款 13-追索 14-同意清偿
     * @param queryType 1-待操作 2-待应答 3-待撤回
     * @return
     */
    private String busiAdnQuery2OpType(String busiType, String queryType) {
        if (StringHelper.isNullOrEmpty(busiType) || StringHelper.isNullOrEmpty(queryType)) {
            return null;
        }
        int busi = Integer.parseInt(busiType);
        int query = Integer.parseInt(queryType);
        switch (query) {
            //1-待操作
            case 1:
                switch (busi) {
                    //1001-出票登记申请
                    case 1:
                        return null;
                    //1002-提示承兑申请
                    case 2:
                        return null;
                    //1003-提示收票申请
                    case 3:
                        return "4";
                    //1004-背书转让申请
                    case 4:
                        return "1";
                    //1005-质押申请
                    case 5:
                        return "15";
                    //1006-可质押解除申请
                    case 6:
                        return "19";
                    //1007-出票保证申请
                    case 7:
                        return "27";
                    //1008-承兑保证申请
                    case 8:
                        return "27";
                    //1009-背书保证申请
                    case 9:
                        return "27";
                    //1010-贴现申请
                    case 10:
                        return "2";
                    //1011-可回购式贴现赎回
                    case 11:
                        return "5";
                    //1012-提示付款申请
                    case 12:
                        return "3";
                    //1013-追索通知申请
                    case 13:
                        return "22";
                    //1014-同意清偿申请
                    case 14:
                        return "24";
                }
                break;
            //2-待应答
            case 2:
                switch (busi) {
                    case 1:
                        return null;
                    //2002-提示承兑签收
                    case 2:
                        return "30";
                    //2003-提示收票签收
                    case 3:
                        return "11";
                    //2004-背书转让签收
                    case 4:
                        return "12";
                    //2005-质押签收
                    case 5:
                        return "17";
                    //2006-质押解除签收
                    case 6:
                        return "18";
                    //2007-出票保证签收
                    case 7:
                        return "28";
                    //2008-承兑保证签收
                    case 8:
                        return "28";
                    //2009-背书保证签收
                    case 9:
                        return "28";
                    //2010-贴现申请签收
                    case 10:
                        return null;
                    //2011-回购式贴现赎回签收
                    case 11:
                        return "13";
                    //2012-提示付款签收
                    case 12:
                        return "14";
                    //2013-追索签收
                    case 13:
                        return null;
                    //2014-同意清偿签收
                    case 14:
                        return "26";
                }
                break;
            //3-待撤回
            case 3:
                switch (busi) {
                    //3001-撤票
                    case 1:
                        return "6";
                    //3002-提示承兑撤回
                    case 2:
                        return null;
                    //3003-提示收票撤回
                    case 3:
                        return "7";
                    //3004-背书转让撤回
                    case 4:
                        return "8";
                    //3005-质押撤回
                    case 5:
                        return "20";
                    //3006-解质押撤回
                    case 6:
                        return "21";
                    //3007-出票保证撤回
                    case 7:
                        return "29";
                    //3008-承兑保证撤回
                    case 8:
                        return "29";
                    //3009-背书保证撤回
                    case 9:
                        return "29";
                    //3010-贴现撤回
                    case 10:
                        return "9";
                    //3011-回购式贴现赎回撤回
                    case 11:
                        return null;
                    //3012-提示付款撤回
                    case 12:
                        return "10";
                    //3013-追索通知撤回
                    case 13:
                        return "23";
                    //3014-同意清偿撤回
                    case 14:
                        return "25";
                }
                break;
        }
        return null;
    }

    public String D_OperBill_Query_Req_TAG(String xml, String tag, ReqB001OperBillQry query, RetAtsB001OperBillQry retAts) throws Exception {
        xml = TAG_PAT.matcher(xml).replaceAll("<NextTag>" + tag + "</NextTag>");

        String[] tmpStrRet = sendToBank(xml);
        StringBuilder tmpSbMsg = new StringBuilder();
        XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);

        String nextTag = null;
        if (tmpStrRet[0].length() == 0) {
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/CMS/eb/pub/RetCode");
                String tmpRetMsg = tmpBkReader.getFirstText("/CMS/eb/pub/RetMsg");
                if (isActiveRetCode(tmpRetCode)) {
                    nextTag = tmpBkReader.getFirstText("/CMS/eb/out/NextTag");
                    while (tmpBkReader.read("/CMS/eb/out/rd")) {
                        RetAtsB001OperBillQryDetail tmpRetDetail = new RetAtsB001OperBillQryDetail();
                        setRetAtsB001OperBillQryDetail(query, tmpRetDetail, tmpBkReader);
                        retAts.writeDetail(tmpRetDetail);
                    }
                } else if (tmpRetCode.equals("B0116")) {
                    retAts.writeRespInfo(tmpRetMsg);
                } else {
                    throw new Exception(tmpRetMsg);
                }
            } else {
                throw new Exception(tmpSbMsg.toString());
            }
        } else {
            throw new Exception(tmpStrRet[1]);
        }
        return nextTag;
    }

    private void setRetAtsB001OperBillQryDetail(ReqB001OperBillQry query, RetAtsB001OperBillQryDetail tmpRetDetail, XmlTextReader tmpBkReader) throws Exception {
        tmpRetDetail.billNo = tmpBkReader.readedXElement.getSingleText("BillNo");
        tmpRetDetail.billType = "AC01".equals(tmpBkReader.readedXElement.getSingleText("BillType"))?"EM001":"EM002";
//        tmpRetDetail.issDate = convertDate8(tmpBkReader.readedXElement.getSingleText("BillOpenDate"));
//        tmpRetDetail.dueDate = convertDate8(tmpBkReader.readedXElement.getSingleText("BillDueDate"));
        tmpRetDetail.issDate = DateHelper.convertD8toD10(tmpBkReader.readedXElement.getSingleText("BillOpenDate"));
        tmpRetDetail.dueDate = DateHelper.convertD8toD10(tmpBkReader.readedXElement.getSingleText("BillDueDate"));
        tmpRetDetail.billAmt = StringHelper.amountDivide100(tmpBkReader.readedXElement.getSingleText("BillAmt"));

        tmpRetDetail.transFlag = reciteFlag2TransFlag(tmpBkReader.readedXElement.getSingleText("ReciteFlag"));
//        tmpRetDetail.MustPay = convertMustPay(tmpBkReader.readedXElement.getSingleText("MustPay"));

        tmpRetDetail.drawName = tmpBkReader.readedXElement.getSingleText("BillOpenName");
//        tmpRetDetail.DrawCode = tmpBkReader.readedXElement.getSingleText("DrawCode");
        tmpRetDetail.drawAct = tmpBkReader.readedXElement.getSingleText("BillOpenAcc");
        tmpRetDetail.drawBnkName = tmpBkReader.readedXElement.getSingleText("BillOpenBank");
//        tmpRetDetail.DrawBnkCode = tmpBkReader.readedXElement.getSingleText("DrawBnkCode");

        tmpRetDetail.accpName = tmpBkReader.readedXElement.getSingleText("AcceptName");
//        tmpRetDetail.AccpCode = tmpBkReader.readedXElement.getSingleText("AccpCode");
        tmpRetDetail.accpAct = tmpBkReader.readedXElement.getSingleText("AcceptAccNo");
        tmpRetDetail.accpBnkName = tmpBkReader.readedXElement.getSingleText("AcceptBank");
        tmpRetDetail.accpBnkCode = tmpBkReader.readedXElement.getSingleText("AcceptBankNo");

        tmpRetDetail.payeeName = tmpBkReader.readedXElement.getSingleText("RecvAccName");
//        tmpRetDetail.PayeeCode = tmpBkReader.readedXElement.getSingleText("PayeeCode");
        tmpRetDetail.payeeAct = tmpBkReader.readedXElement.getSingleText("RecvAccNo");
        tmpRetDetail.payeeBnkName = tmpBkReader.readedXElement.getSingleText("RecvBankName");
//        tmpRetDetail.PayeeBnkCode = tmpBkReader.readedXElement.getSingleText("PayeeBnkCode");

        tmpRetDetail.busiNo = tmpBkReader.readedXElement.getSingleText("BankTranSerial");
        tmpRetDetail.busiType = query.detail.busiType;
        tmpRetDetail.queryType = query.detail.queryType;
//        tmpRetDetail.ApplyReq = tmpBkReader.readedXElement.getSingleText("ApplyReq");
//        tmpRetDetail.ApplyDate = tmpBkReader.readedXElement.getSingleText("ApplyDate");
//
            //tmpRetDetail.ApplyCode = tmpBkReader.readedXElement.getSingleText("ApplyCode");
        //tmpRetDetail.ApplyBnkCode = tmpBkReader.readedXElement.getSingleText("ApplyBnkCode");

//        tmpRetDetail.ReceName = tmpBkReader.readedXElement.getSingleText("RecvAccName");
//        tmpRetDetail.ReceCode = tmpBkReader.readedXElement.getSingleText("ReceCode");
        tmpRetDetail.receAct = tmpBkReader.readedXElement.getSingleText("SignAccNo");
        if(query.detail.queryType.equals("3")&&"13".equals(query.detail.busiType)){
            if(tmpRetDetail.receAct.equals(tmpRetDetail.drawAct)){
                tmpRetDetail.receName = tmpRetDetail.drawName;
                tmpRetDetail.receBnkCode = tmpRetDetail.drawBnkCode;
                tmpRetDetail.receBnkName = tmpRetDetail.drawBnkName;
            }else if(tmpRetDetail.receAct.equals(tmpRetDetail.accpAct)){
                    tmpRetDetail.receName = tmpRetDetail.accpName;
                    tmpRetDetail.receBnkCode = tmpRetDetail.accpBnkCode;
                    tmpRetDetail.receBnkName = tmpRetDetail.accpBnkName;
                }
            }
//        tmpRetDetail.ReceBnkName = tmpBkReader.readedXElement.getSingleText("RecvBankName");
//        tmpRetDetail.ReceBnkCode = tmpBkReader.readedXElement.getSingleText("ReceBnkCode");

        tmpRetDetail.memo = tmpBkReader.readedXElement.getSingleText("Remark");
        tmpRetDetail.contractNo = tmpBkReader.readedXElement.getSingleText("ContractNo");
        tmpRetDetail.invoiceNo = tmpBkReader.readedXElement.getSingleText("InvoiceNo");
//        tmpRetDetail.DiscType = tmpBkReader.readedXElement.getSingleText("DiscType");
//        tmpRetDetail.PayType = tmpBkReader.readedXElement.getSingleText("PayType");
//
//        tmpRetDetail.RepOpenDate = tmpBkReader.readedXElement.getSingleText("RepOpenDate");
//        tmpRetDetail.RepDueDate = tmpBkReader.readedXElement.getSingleText("RepDueDate");
//        tmpRetDetail.DiscRate = tmpBkReader.readedXElement.getSingleText("DiscRate");
//        tmpRetDetail.RepRate = tmpBkReader.readedXElement.getSingleText("RepRate");
//        tmpRetDetail.ActedAct = tmpBkReader.readedXElement.getSingleText("ActedAct");
//        tmpRetDetail.ActedBnkCode = tmpBkReader.readedXElement.getSingleText("ActedBnkCode");
//        tmpRetDetail.OverDueRea = tmpBkReader.readedXElement.getSingleText("OverDueRea");
//
//        tmpRetDetail.RecourseType = tmpBkReader.readedXElement.getSingleText("RecourseType");
//        tmpRetDetail.RecourseAmt = tmpBkReader.readedXElement.getSingleText("RecourseAmt");
//        tmpRetDetail.RecourseCode = tmpBkReader.readedXElement.getSingleText("RecourseCode");
        tmpRetDetail.billStatus = tmpBkReader.readedXElement.getSingleText("BillStat");

        String opType = busiAdnQuery2OpType(query.detail.busiType, query.detail.queryType);
        if (opType == null) return;

        /**
         * 操作类型非16-可查验时返回，
         * 1-4位定长返回追索类型，RT00：拒付追索RT01：非拒付追索；
         * 5-8位返回追索理由，RC00：承兑人被依法宣告破产RC01：承兑人因违法被责令终止活动；
         * 从第9位-96位每8位定长依次返回以下日期，
         * 票据开立日期、8-16
         * 提示付款日期、16-24
         * 提示付款预约网银提交日期、24-32
         * 提示收票日期、32-40
         * 贴现申请日期、40-48
         * 保证申请日期、48-56
         * 追索申请日期、56-64
         * 清偿日期、64-72
         * 背书转让日期、72-80
         * 质押申请日期、80-88
         * 质押解除日期、88-96
         */
        String repReserved7 = tmpBkReader.readedXElement.getSingleText("RepReserved7");
        if (!opType.equals("16")) {
            tmpRetDetail.recourseType = convertRecourseType(repReserved7.substring(0, 4));
            tmpRetDetail.recourseCode = convertRecourseCode(repReserved7.substring(4, 8));
        }

        //根据操作类型返回对应交易对手信息
        String opponent = tmpBkReader.readedXElement.getSingleText("RepReserved8");
        if (opponent == null || opponent.trim().equals("")) {
            return;
        }
        String[] value = opponent.split("\\|");
        if (value.length == 0) {
            return;
        }

        //23-可追索撤回      返回被追索人账号列表，以|分隔
        if (opType.equals("23")) {

        }
        //除23以外的操作,返回结果都为3个,被追索人账号列表数量不确定
        if (value.length != 3&&value.length != 2) {
            return;
        }
        switch (Integer.parseInt(opType)) {
            //不返回
            //1-可背书转让
            case 1:
                //2-可贴现
            case 2:
                //3-可提示付款
            case 3:
                //4-可提示收票
            case 4:
                //5-可贴现赎回
            case 5:
                //6-可撤票
            case 6:
                //15-可质押
            case 15:
                //16-可查验
            case 16:
                //22-可追索
            case 22:
                break;
            //7-可提示收票撤回     收票人账号、户名、行号
            case 7:
                setApply(tmpRetDetail, tmpBkReader);
                setRec(tmpRetDetail, value);
                break;
            //8-可背书转让撤回     被背书人账号、户名、行号
            case 8:
                setApply(tmpRetDetail, tmpBkReader);
                setRec(tmpRetDetail, value);
                break;
            //9-可贴现撤回         贴入行信息，账号固定返回0，贴入行全称，贴入行行号
            case 9:
                setApply(tmpRetDetail, tmpBkReader);
                setRec(tmpRetDetail, value);
                break;
            //10-可提示付款撤回     承兑人或承兑行账号、户名、行号
            case 10:
                setApply(tmpRetDetail, tmpBkReader);
                setRec(tmpRetDetail, value);
                break;
            //11-可提示收票签收   出票人账号、户名、行号
            case 11:
                setApply(tmpRetDetail, value);
//                setRec(tmpRetDetail, tmpBkReader);
                break;
            //12-可背书转让签收   背书人账号、户名、行号
            case 12:
                setApply(tmpRetDetail, value);
//                setRec(tmpRetDetail, tmpBkReader);
                break;
            //13-可贴现赎回签收   贴入行信息，账号固定返回0，贴入行全称，贴入行行号
            case 13:
                setApply(tmpRetDetail, value);
//                setRec(tmpRetDetail, tmpBkReader);
                break;
            //14-可提示付款签收   持票人账号、户名、行号
            case 14:
                setApply(tmpRetDetail, value);
//                setRec(tmpRetDetail, tmpBkReader);
                break;
            //17-可质押签收      出质人账号、户名，行号暂时不能返回
            case 17:
                setApply(tmpRetDetail, value);
//                setRec(tmpRetDetail, tmpBkReader);
                break;
            //18-可质押解除签收    出质人账号、户名，行号暂时不能返回
            case 18:
                setApply(tmpRetDetail, value);
//                setRec(tmpRetDetail, tmpBkReader);
                break;
            //19-可质押解除    出质人账号、户名，行号暂时不能返回
            case 19:
                setApply(tmpRetDetail, tmpBkReader);
                setRec(tmpRetDetail, value);
                break;
            //20-可质押撤回     质权人账号、户名、行号
            case 20:
                setApply(tmpRetDetail, tmpBkReader);
                setRec(tmpRetDetail, value);
                break;
            //21-可质押解除撤回    出质人账号、户名，行号暂时不能返回
            case 21:
                setApply(tmpRetDetail, tmpBkReader);
                setRec(tmpRetDetail, value);
                break;
            //24-可同意清偿      追索人账号、户名，行号暂时不能返回
            case 24:
                setApply(tmpRetDetail, value);
//                setRec(tmpRetDetail, tmpBkReader);
                break;
            //25-可同意清偿撤回    追索人账号、户名，行号暂时不能返回
            case 25:
//                setApply(tmpRetDetail, tmpBkReader);
                setApply(tmpRetDetail, value);
                break;
            //26-可同意清偿签收   清偿人（即被追索人）账号、户名，行号暂时不能返回
            case 26:
                setApply(tmpRetDetail, value);
                setRec(tmpRetDetail, tmpBkReader);
                break;
            //28-可保证撤回      返回保证人名称|保证人账号|保证人开户行号
            case 28:
                setApply(tmpRetDetail, tmpBkReader);
                setRec(tmpRetDetail, value);
                break;
            //29-可保证签收      返回被保证人名称|被保证人账号|被保证人开户行号
            case 29:
                setApply(tmpRetDetail, value);
                setRec(tmpRetDetail, tmpBkReader);
                break;
            //30-可提示承兑签收    返回申请人名称|申请人账号|申请人开户行号
            case 30:
                setApply(tmpRetDetail, value);
//                setRec(tmpRetDetail, tmpBkReader);
                break;
        }
    }

    /**
     * 银行billType转为ats中billType bank → ats
     * <p>
     * ats : 1-银承 2-商承
     * bank : AC01-银承 AC02-商承
     *
     * @param billType
     * @return
     */
    private String convertBillType(String billType) {
        if (billType == null) return null;
        if (billType.equals("AC01")) {
            return "1";
        }
        if (billType.equals("AC02")) {
            return "2";
        }
        return billType;
    }

    /**
     * 银行返回的YYYYMMDD 格式时间转为 yyyy-MM-dd HH:mm:ss
     *
     * @param date
     * @return
     * @throws ParseException
     */
    private String convertDate8(String date) throws ParseException {
        if (date == null) return null;
        return Format.DateTimeFormat.format(Format.Date8Format.parse(date));
    }

    /**
     * 禁止背书转让标识转换 bank → ats
     * ats 1-可再转让 0-不得转让
     * <p>
     * EM00 可再转让
     * EM01 不再转让
     *
     * @param reciteFlag
     * @return
     */
    private String reciteFlag2TransFlag(String reciteFlag) {
        if (reciteFlag == null) return null;
        if (reciteFlag.equals("EM00")) {
            return "1";
        }
        if (reciteFlag.equals("EM01")) {
            return "0";
        }
        return reciteFlag;
    }

    /**
     * bank → ats
     * bank RT00-拒付追索 RT01-非拒付追索
     * ats  1-拒付追索 2-非拒付追索
     *
     * @param recourseType
     * @return
     */
    private String convertRecourseType(String recourseType) {
        if (recourseType == null) return null;
        if (recourseType.equals("RT00")) {
            return "1";
        }
        if (recourseType.equals("RT01")) {
            return "2";
        }
        return null;
    }

    /**
     * bank → ats
     * bank RC00：承兑人被依法宣告破产 RC01：承兑人因违法被责令终止活动
     * ats  追索理由代码（非拒付时） 1-承兑人被依法宣告破产 2-承兑人因违法被责令终止活动
     *
     * @param recourseCode
     * @return
     */
    private String convertRecourseCode(String recourseCode) {
        if (recourseCode == null) return null;
        if (recourseCode.equals("RC00")) {
            return "1";
        }
        if (recourseCode.equals("RC01")) {
            return "2";
        }
        return null;
    }

    /**
     * 撤回 操作申请人为当前持票人
     *
     * @param tmpRetDetail
     * @param tmpBkReader
     */
    private void setApply(RetAtsB001OperBillQryDetail tmpRetDetail, XmlTextReader tmpBkReader) throws Exception {
        tmpRetDetail.applyName = tmpBkReader.readedXElement.getSingleText("BillHoldName");
        tmpRetDetail.applyAct = tmpBkReader.readedXElement.getSingleText("BillHoldAcc");
        tmpRetDetail.applyBnkName = tmpBkReader.readedXElement.getSingleText("BillHoldBank");
    }

    /**
     * 撤回 操作接收人为交易对手,设置接收人信息 账号 + 全称 + 银行行号
     *
     * @param tmpRetDetail
     * @param value
     */
    private void setRec(RetAtsB001OperBillQryDetail tmpRetDetail, String[] value) {
        tmpRetDetail.receAct = value[0];
        tmpRetDetail.receName = value[1];
        if(value.length==3) {
        tmpRetDetail.receBnkCode = value[2];
        }
    }

    /**
     * 签收 操作申请人为交易对手
     *
     * @param tmpRetDetail
     * @param value
     */
    private void setApply(RetAtsB001OperBillQryDetail tmpRetDetail, String[] value) {
        tmpRetDetail.applyAct = value[0];
        tmpRetDetail.applyName = value[1];
        if(value.length==3) {
        tmpRetDetail.applyBnkCode = value[2];
        }
    }

    /**
     * 签收 操作接收人为当前用户
     *
     * @param tmpRetDetail
     * @param tmpBkReader
     * @throws Exception
     */
    private void setRec(RetAtsB001OperBillQryDetail tmpRetDetail, XmlTextReader tmpBkReader) throws Exception {
        tmpRetDetail.receAct = tmpBkReader.readedXElement.getSingleText("BillHoldName");
        tmpRetDetail.receName = tmpBkReader.readedXElement.getSingleText("BillHoldAcc");
        tmpRetDetail.receBnkName = tmpBkReader.readedXElement.getSingleText("BillHoldBank");
    }

    /**
     * 根据busiType和OperType转为对应的操作类型,用于生成对应ats系统中状态码
     * busiType = 1, operType = 1 return 1001
     *
     * @param busiType
     * @param operType
     * @return
     */
    private String completeOperType(String busiType, String operType) {
        String operflag = "";
        int busiLength = busiType.trim().length();
        int operLength = operType.trim().length();
        if (busiLength == 1) {
            operflag += busiType + "0";
        } else if (busiLength == 2) {
            operflag += busiType;
        }
        if (operLength == 1) {
            operflag += "0" + operType;
        } else if (operLength == 2) {
            operflag += operType;
        }
        return operflag;
    }

    private void setRetAtsB007BillKzsrQryDetail(ReqB007BillKzsrQry query, RetAtsB007BillKzsrQryDetail tmpRetDetail, XmlTextReader tmpBkReader) throws Exception {
        tmpRetDetail.receName = tmpBkReader.readedXElement.getSingleText("RecvAccName");
//        tmpRetDetail.ReceCode = tmpBkReader.readedXElement.getSingleText("ReceCode");
        tmpRetDetail.receAct = tmpBkReader.readedXElement.getSingleText("RecvAccNo");
        tmpRetDetail.receBnkName = tmpBkReader.readedXElement.getSingleText("RecvBankName");
//        tmpRetDetail.ReceBnkCode = tmpBkReader.readedXElement.getSingleText("ReceBnkCode");
    }
}

